/*
 * Copyright (c) 2011 Ball State University
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * NOTE:
 * Derivative work based on the Google IO 2011 Schedule app released for open source
 * http://code.google.com/p/iosched/
 */

package edu.bsu.android.gtv.apps.bconnected.ui;

import java.util.ArrayList;

import edu.bsu.android.gtv.apps.bconnected.util.UIUtils;
import edu.bsu.android.gtv.apps.bconnected.data.EventTypeData;
import edu.bsu.android.gtv.apps.bconnected.util.Constants;
import edu.bsu.android.gtv.apps.bconnected.R;
import edu.bsu.android.gtv.apps.bconnected.data.EventData;
import edu.bsu.android.gtv.apps.bconnected.data.MonthData;
import edu.bsu.android.gtv.apps.bconnected.objects.Event;
import edu.bsu.android.gtv.apps.bconnected.util.Adapters;
import edu.bsu.android.gtv.apps.bconnected.util.AnalyticsUtils;
import edu.bsu.android.gtv.apps.bconnected.util.PersistentListFragment;

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.app.ListFragment;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;

/**
 * A {@link ListFragment} showing a list of events based on the month selected.  The listfragment appears in the right hand column of the 
 * {@link EventMultiPaneActivity} after the user selects a month.  Once an item is selected, the {@link EventInfoActivity} activity
 * is started.
 * @author Kyle Parker, University Computing Services
 */
public class EventFragment extends PersistentListFragment {
    private static final String TAG = "EventFragment";
    
	private OnEventListener mEventListener = null;
    private Adapters.EventAdapter mEventAdapter;
	private boolean persistentSelection = false;
    
    private ArrayList<Event> mEvents;
    private Activity mActivity;
    
    private int mPosition = 0;
    private int mTarget = 0;

	public EventFragment() {
		this(false);
	}
	
	public EventFragment(boolean persistentSelection) {
		this.persistentSelection = persistentSelection;
	}
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
		setRetainInstance(true);
    }

	@Override
	public void onActivityCreated(Bundle state) {
		super.onActivityCreated(state);
		
		mActivity = getActivity();

        AnalyticsUtils.getInstance(mActivity).trackPageView("/Events");
		registerForContextMenu(getListView());
		restoreState(state);
		
		if (persistentSelection) {
			enablePersistentSelection();
		}

        reloadFromArguments(getArguments());
		
    	mEvents = new ArrayList<Event>();
    	mEventAdapter = new Adapters.EventAdapter(mActivity, R.layout.list_item, mEvents, mTarget);
        
    	Drawable selector = mActivity.getResources().getDrawable(R.drawable.left_pane_shadow); 
    	getListView().setBackgroundDrawable(selector);
        setListAdapter(this.mEventAdapter); 
    	setListShown(false);
        
        loadEvents();
        setHasOptionsMenu(true);
	}

    /**
     * Convert the fragment arguments to intents for use during the activity lifecycle
     */
    public void reloadFromArguments(Bundle arguments) { 
        final Intent intent = edu.bsu.android.gtv.apps.bconnected.ui.base.BaseActivity.fragmentArgumentsToIntent(arguments);
        
		Bundle extras = intent.getExtras();   
		if (extras != null) {
			if (extras.getString(Constants.EXTRA_TARGET_FRAGMENT) != null) {
				mTarget = Integer.parseInt(extras.getString(Constants.EXTRA_TARGET_FRAGMENT));
			}
		}
    }
    
    /** {@inheritDoc} */
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		
		if (mEventListener != null) {
			mEventListener.onEventSelected(mEventAdapter.getItem(position), mTarget);
		}
    }

    /**
     * Method called by the ConnectionFragment to launch the activity and set the necessary values for the web service calls
     * @param position
     */
    public void startActivity(final int position) {
    	mPosition = position;
    	
    	if (mActivity != null) {
    		loadEvents();
    	}
    }

    /**
     * Using a new thread, separate from the main activity, load the event information from the service handler
     */
    private void loadEvents() { 
        Runnable load = new Runnable(){
            public void run() {
            	mEvents = new ArrayList<Event>();
            	
            	try {
            		switch (mTarget) {
	        			case Constants.TARGET_EVENT_MONTH:
	                		if (MonthData.getMonthCount() > 0) {
	    		    	        int monthID = MonthData.getMonth(mPosition).getMonthID();
	    		    	        int year = MonthData.getMonth(mPosition).getYear();
	    		    	        
	    		    	        EventData.initializeEvent(monthID, year, mActivity);
	    		
	    		                if (EventData.getEventCount() > 0) {
	    		                	mEvents = EventData.getEvents();
	    		                }
	                		}
	        				break;
	        			case Constants.TARGET_EVENT_TYPE:
	        				if (EventTypeData.getEventTypeCount() > 0) {
	                			String eventTypeID = EventTypeData.getEventType(mPosition).getCalendarEventID();
	                			
	    		    	        EventData.initializeEventType(eventTypeID, mActivity);
	    		
	    		                if (EventData.getEventCount() > 0) {
	    		                	mEvents = EventData.getEvents();
	    		                }
	                		}
	        				break;
	            	}

            		mActivity.runOnUiThread(returnEvent);
            	} catch (Exception ex) {
                    AnalyticsUtils.getInstance(mActivity).trackPageView(TAG + ": " + ex.getMessage());
            	}
            }
        };

        Thread thread = new Thread(null, load, "loadEvents");
        thread.start();
        
        if (mActivity != null) {
        	setListShown(false);
        }
    }
    
    /**
     * Add each event object from the service handler to the array adapter and set the visibility of the spinner to "gone"
     */
    private Runnable returnEvent = new Runnable(){
        public void run() {
        	if (mEventAdapter.getCount() > 0) {
        		mEventAdapter.clear();
        	}
        	
            if (mEvents != null && mEvents.size() > 0){
                for(int i = 0; i < mEvents.size(); i++) {
                	mEventAdapter.add(mEvents.get(i));
                }
                
                // If there are items, the list needs to enabled (or re-enabled in the event a blank list was loaded initially)
            	getListView().setEnabled(true);
            } else {
            	Event empty = new Event();
            	
        		switch (mTarget) { 
	    			case Constants.TARGET_EVENT_MONTH:
	                	empty.setError(mActivity.getString(R.string.empty_event_month));
	    				break;
	    			case Constants.TARGET_EVENT_TYPE:
	                	empty.setError(mActivity.getString(R.string.empty_event_type));
	    				break;
	        	}
            	mEventAdapter.add(empty);
            	
            	// If there are no items returned, disable the list selection
            	getListView().setEnabled(false);
            }

            mEventAdapter.notifyDataSetChanged();
            setListShown(true);
        }
    };

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.event_menu_items, menu);
        super.onCreateOptionsMenu(menu, inflater); 
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        final Intent intent;

        switch (item.getItemId()) {
	        case R.id.menu_switch_view:
                int view = UIUtils.getLastID(mActivity, Constants.PREF_EVENT_VIEW);
                
                if (view == Constants.TARGET_EVENT_MONTH || view == 0) {
                	UIUtils.setLastID(mActivity, Constants.PREF_EVENT_VIEW, Constants.TARGET_EVENT_TYPE);

    				intent = new Intent(Intent.ACTION_VIEW, null, mActivity, EventMultiPaneActivity.class); 	  	
                    intent.putExtra(Constants.EXTRA_TARGET_FRAGMENT, Integer.toString(Constants.TARGET_EVENT_TYPE));
                } else {
                	UIUtils.setLastID(mActivity, Constants.PREF_EVENT_VIEW, Constants.TARGET_EVENT_MONTH);

    				intent = new Intent(Intent.ACTION_VIEW, null, mActivity, EventMultiPaneActivity.class);
                    intent.putExtra(Constants.EXTRA_TARGET_FRAGMENT, Integer.toString(Constants.TARGET_EVENT_MONTH));
                }

                startActivity(intent);
                
                mActivity.finish();
	            return true;
        }
        
        return super.onOptionsItemSelected(item);
    }
    
	public void setOnEventListener(OnEventListener listener, int target) {
		this.mEventListener = listener;
		this.mTarget = target;
	}	
	
	public interface OnEventListener {
		void onEventSelected(Event event, int mTarget);
	}
}
